using System;

using Microsoft.VisualStudio.TestTools.UnitTesting;
using Pegasus.Diagnostics;

namespace Pegasus.UnitTests.Diagnostics
{
	/// <summary>
	/// Unit test for the ParamCode static object
	/// </summary>
	[TestClass]
	public class ParamCodeTest
	{
		// Local Instance Values
		private TestContext m_testContextInstance;
		private string m_messageWithParams;

		// Local Const Values
		private const string ParameterName = "ParameterName";
		private const string TestFailedExceptionTest = "Assert failed to act correctly";
		private const string MessageFormat = "TheMessage {0} {1} {2}";
		private const string MessageArg1 = "TheString";
		private const int MessageArg2 = 123;
		private readonly Guid MessageArg3 = Guid.Empty;

		/// <summary>
		/// Initializes a new instance of the <see cref="T:ParamCodeTest"/> class.
		/// </summary>
		public ParamCodeTest()
		{
			m_messageWithParams = string.Format( MessageFormat, MessageArg1, MessageArg2, MessageArg3 );
		}

		/// <summary>
		/// Gets or sets the test context which provides information about and 
		/// functionality for the current test run.
		/// </summary>
		/// <value>The test context.</value>
		public TestContext TestContext
		{
			get
			{
				return m_testContextInstance;
			}
			set
			{
				m_testContextInstance = value;
			}
		}

		/// <summary>
		/// Test the assert methods.
		/// </summary>
		[TestMethod]
		public void ParamCodeAssertTest1()
		{
			// Assert passes
			ParamCode.Assert( true, ParameterName );

			try
			{
				// Assert fails
				ParamCode.Assert( false, ParameterName );
			}
			catch( ArgumentException e )
			{
				if( e.Message.Contains( ParameterName ) &&
					e.Message.Contains( "ParamCodeAssertTest1" ) )
				{
					return;
				}
			}

			throw new Exception( TestFailedExceptionTest );
		}

		/// <summary>
		/// Test the assert methods.
		/// </summary>
		[TestMethod]
		public void ParamCodeAssertTest2()
		{
			// Assert passes
			ParamCode.Assert( true, ParameterName, MessageFormat, MessageArg1, MessageArg2, MessageArg3 );

			try
			{
				// Assert fails
				ParamCode.Assert( false, ParameterName, MessageFormat, MessageArg1, MessageArg2, MessageArg3 );
			}
			catch( ArgumentException e )
			{
				if( e.Message.Contains( ParameterName ) &&
					e.Message.Contains( "ParamCodeAssertTest2" ) &&
					e.Message.Contains( m_messageWithParams ) )
				{
					return;
				}
			}

			throw new Exception( TestFailedExceptionTest );
		}

		/// <summary>
		/// Test the assert null methods.
		/// </summary>
		[TestMethod]
		public void ParamCodeAssertNullTest1()
		{
			// Assert passes
			ParamCode.AssertNull( null, ParameterName );

			try
			{
				// Assert fails
				ParamCode.AssertNull( new object(), ParameterName );
			}
			catch( ArgumentException e )
			{
				if( e.Message.Contains( ParameterName ) &&
					e.Message.Contains( "ParamCodeAssertNullTest1" ) )
				{
					return;
				}
			}

			throw new Exception( TestFailedExceptionTest );
		}

		/// <summary>
		/// Test the assert null methods.
		/// </summary>
		[TestMethod]
		public void ParamCodeAssertNullTest2()
		{
			// Assert passes
			ParamCode.AssertNull( null, ParameterName, MessageFormat, MessageArg1, MessageArg2, MessageArg3 );

			try
			{
				// Assert fails
				ParamCode.AssertNull( new object(), ParameterName, MessageFormat, MessageArg1, MessageArg2, MessageArg3 );
			}
			catch( ArgumentException e )
			{
				if( e.Message.Contains( ParameterName ) &&
					e.Message.Contains( "ParamCodeAssertNullTest2" ) &&
					e.Message.Contains( m_messageWithParams ) )
				{
					return;
				}
			}

			throw new Exception( TestFailedExceptionTest );
		}

		/// <summary>
		/// Test the assert not null methods.
		/// </summary>
		[TestMethod]
		public void ParamCodeAssertNotNullTest1()
		{
			// Assert passes
			ParamCode.AssertNotNull( new object(), ParameterName );

			try
			{
				// Assert fails
				ParamCode.AssertNotNull( null, ParameterName );
			}
			catch( ArgumentException e )
			{
				if( e.Message.Contains( ParameterName ) &&
					e.Message.Contains( "ParamCodeAssertNotNullTest1" ) )
				{
					return;
				}
			}

			throw new Exception( TestFailedExceptionTest );
		}

		/// <summary>
		/// Test the assert not null methods.
		/// </summary>
		[TestMethod]
		public void ParamCodeAssertNotNullTest2()
		{
			// Assert passes
			ParamCode.AssertNotNull( new object(), ParameterName, MessageFormat, MessageArg1, MessageArg2, MessageArg3 );

			try
			{
				// Assert fails
				ParamCode.AssertNotNull( null, ParameterName, MessageFormat, MessageArg1, MessageArg2, MessageArg3 );
			}
			catch( ArgumentException e )
			{
				if( e.Message.Contains( ParameterName ) &&
					e.Message.Contains( "ParamCodeAssertNotNullTest2" ) &&
					e.Message.Contains( m_messageWithParams ) )
				{
					return;
				}
			}

			throw new Exception( TestFailedExceptionTest );
		}

		/// <summary>
		/// Test the assert not empty (string) null methods.
		/// </summary>
		[TestMethod]
		public void ParamCodeAssertNotEmptyStringTest1()
		{
			// Assert passes
			ParamCode.AssertNotEmpty( "test", ParameterName );

			try
			{
				// Assert fails
				ParamCode.AssertNotEmpty( string.Empty, ParameterName );
			}
			catch( ArgumentException e )
			{
				if( e.Message.Contains( ParameterName ) &&
					e.Message.Contains( "ParamCodeAssertNotEmptyStringTest1" ) )
				{
					return;
				}
			}

			throw new Exception( TestFailedExceptionTest );
		}

		/// <summary>
		/// Test the assert not empty (string) null methods.
		/// </summary>
		[TestMethod]
		public void ParamCodeAssertNotEmptyStringTest2()
		{
			// Assert passes
			ParamCode.AssertNotEmpty( "test", ParameterName );

			try
			{
				// Assert fails
				string test = null;
				ParamCode.AssertNotEmpty( test, ParameterName );
			}
			catch( ArgumentException e )
			{
				if( e.Message.Contains( ParameterName ) &&
					e.Message.Contains( "ParamCodeAssertNotEmptyStringTest2" ) )
				{
					return;
				}
			}

			throw new Exception( TestFailedExceptionTest );
		}


		/// <summary>
		/// Test the assert not empty (string) null methods.
		/// </summary>
		[TestMethod]
		public void ParamCodeAssertNotEmptyStringTest3()
		{
			// Assert passes
			ParamCode.AssertNotEmpty( "test", ParameterName, MessageFormat, MessageArg1, MessageArg2, MessageArg3 );

			try
			{
				// Assert fails
				ParamCode.AssertNotEmpty( string.Empty, ParameterName, MessageFormat, MessageArg1, MessageArg2, MessageArg3 );
			}
			catch( ArgumentException e )
			{
				if( e.Message.Contains( ParameterName ) &&
					e.Message.Contains( "ParamCodeAssertNotEmptyStringTest3" ) &&
					e.Message.Contains( m_messageWithParams ) )
				{
					return;
				}
			}

			throw new Exception( TestFailedExceptionTest );
		}

		/// <summary>
		/// Test the assert not empty (string) null methods.
		/// </summary>
		[TestMethod]
		public void ParamCodeAssertNotEmptyStringTest4()
		{
			// Assert passes
			ParamCode.AssertNotEmpty( "test", ParameterName, MessageFormat, MessageArg1, MessageArg2, MessageArg3 );

			try
			{
				// Assert fails
				string test = null;
				ParamCode.AssertNotEmpty( test, ParameterName, MessageFormat, MessageArg1, MessageArg2, MessageArg3 );
			}
			catch( ArgumentException e )
			{
				if( e.Message.Contains( ParameterName ) &&
					e.Message.Contains( "ParamCodeAssertNotEmptyStringTest4" ) &&
					e.Message.Contains( m_messageWithParams ) )
				{
					return;
				}
			}

			throw new Exception( TestFailedExceptionTest );
		}
	}
}
